package com.xiaoyu.im.request.flow;

import com.xiaoyu.im.ChatToken;
import com.xiaoyu.im.client.IMClient;
import com.xiaoyu.im.datamodel.IMOnlineStatus;
import com.xiaoyu.im.provider.ConversationManager;
import com.xiaoyu.im.request.MessageRequest;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.xiaoyu.im.datamodel.MessageStatus.*;

public class BaseCheckAction implements FlowAction {

    protected final List<CheckSubAction> checkList = new LinkedList<>();

    public BaseCheckAction() {
        checkList.add(BaseCheckAction::checkOnlineStatus);
        checkList.add(BaseCheckAction::checkForCid);
    }

    @Override
    public void exec(MessageRequest request) {
        final int initStatus = request.getStatus();
        for (CheckSubAction action : checkList) {
            action.exec(request);

            boolean failure = initStatus != request.getStatus();
            if (failure) {
                RequestFlow.evolveToNextStatus(request);
                return;
            }
        }
        request.setStatus(CHECKED);
        RequestFlow.evolveToNextStatus(request);
    }

    private static void checkOnlineStatus(MessageRequest request) {
        checkOnlineStatusProcess(request, 0);
    }

    private static void checkOnlineStatusProcess(MessageRequest request, int count) {
        String status = IMClient.getInstance().getOnlineStatus();
        if (!status.equals(IMOnlineStatus.LOGINED)) {
            // Try to solve im error for code = 408 (send message when im not login)
            if (status.equals(IMOnlineStatus.UNLOGIN) || status.equals(IMOnlineStatus.LOGINING)
                    || status.equals(IMOnlineStatus.DISCONNECTED) || status.equals(IMOnlineStatus.CONNECTING)) {
                if (count >= 15) {
                    request.setStatus(NETWORK_INVALID);
                    return;
                }
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                checkOnlineStatusProcess(request, count + 1);
            } else {
                request.setStatus(NETWORK_INVALID);
            }
        }
    }

    private static void checkForCid(MessageRequest request) {
        ChatToken chatToken = request.getPendingMessage().chatToken;
        if (!chatToken.hasChatId() && chatToken.hasUid()) {
            ConversationManager.getInstance().ensureConversationByUid(chatToken.getUid(), request.getFromType());
        }
        if (!chatToken.hasChatId()) {
            request.setStatus(NOT_CID_FAILED);
        }
    }

    protected interface CheckSubAction {

        void exec(MessageRequest request);
    }
}
